<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    /*
    * 作用域：变量的生效范围，在哪些地方可以进行访问
    *   全局作用域：
    *       写在最外层的
    *   函数作用域：
    *       函数内部声明的变量，只能在函数内部访问
    *
    *   块级作用域：ES6 伴随着let const 一起出现的内容
    *       代码块内部声明的变量
    *       var 声明的变量 是可以突破代码块被外界访问的
    *       let/const 声明的变量 是锁定在代码块中的
    *
    *   函数传值：传的是值，而不是变量
    *   如：
    *   let a = 1
    *
    *   function foo(a){ //形参a相当于一开始就在函数内部声明了一个变量a，但仅仅只是声明，具体赋值要看接下来实参中传递了什么值
    *       console.log(a) //因为没有传值，所以默认值就是undefined 所以就会打印undefined
    *   }
    *
    *   foo() //实参中并未传值
    *
    *   再如：
    *   let a = 1
    *
    *   function foo(a){
    *       a = 2 //这里的a改的是谁？改的是函数内部的变量a 浏览器解析时需要去找这个a属于哪里 再给它赋值为2(从一开始的形参a值为1 改成a值为2)
    *       console.log(a) //这里打印的是函数内部的a的值 就是改过之后的值 1 这个操作仅仅只发生在函数内部 函数外全局a的值并未改变
    *   }
    *
    *   foo(a) //将全局的a的值1赋值给这个实参a 此时实参a的值为1 值1再传递给函数的形参a
    *
    *   console.log(a) //这里打印的是全局的a的值2 全局的a并未受到影响 因为没有被改过
    *
    *   再如：
    *   let a = {
    *       name:"银时"
    *   }
    *
    *   function foo(a){ // 先接收了属性name为银时的对象a
    *       a = 2 // 将a的值从一个属性name为银时的对象a 改成了a的值为2 即把a从一个对象改成了一个数值
    *       console.log(a) // 打印函数内部改过了值后的a的值
    *   }
    *
    *   foo(a) //这里将全局中的a 的值 赋值给了 实参a 就是一个属性name为银时的对象
    *   console.log(a) // 这里依旧是全局那个没有改动过的对象a
    *
    *
    * */

    /*
    *   普通类型(值类型)
    *       除了对象都是普通类型，在赋值的过程中，都是类似于抄作业，就是把值抄了过去
    *
    *   引用类型
    *       记录了谁去使用这个对象
    *
    *   如：
    *   let a = { // 全局变量a 指向了这个对象
    *       name:"银时"
    *   }
    *
    *   function foo(a){ // 形参a接收了实参a的值 注意 这里的形参a与外面的全局变量a是不同的a 但是他们俩指向的对象都是同一个 因为形参a接收了来自实参a的值，形参a等于实参a
    *                       形参a的指向就是实参a的指向 而实参a的指向是引用了全局变量a的指向 所以形参a 和全局变量a 都指向了同一个对象
    *       a.name = "sherry" // 所以这里改了形参a所指向的对象的name属性 又因为从头到尾就只有一个对象 所以也就是改了全局变量a所指向的那个对象的name属性
    *       console.log(a) // 这里打印形参a的值 也就是打印对象 因为a的值就是对象
    *   }
    *
    *   foo(a) // 将全局变量a的值传递给了实参a 值就是上面那个对象
    *   console.log(a) // 全局变量a所指向的对象的name属性被修改过 所以就打印出 修改后的对象
    *
    *   再如：
    *   let a = { //创建一个对象 全局变量a指向这个对象 这个对象现在暂时叫银时
    *       name:"银时"
    *   }
    *
    *   function foo(b){ //形参b接收实参a的值 实参a指向 全局变量a所指向的对象银时 所以形参b现在的值就是对象银时
    *       b.name = "sherry" //现在把形参b所指向的对象name属性改成sherry 又因为这个对象也是全局变量a所指向的对象 所以形参b和全局变量a所指向的对象的name属性都被改成了sherry
    *       b = { //现在又把形参b重新指向了一个新创建的对象 这个对象暂时叫阿飞 注意 形参b指向了新创建的对象 但是全局变量a还是指向原先那个被改成sherry的对象
    *           name:"阿飞"
    *       }
    *       b.name = "银时" //现在又把形参b所指向的新的对象的name属性改成银时
    *       return b //返回形参b的值 也就是新对象银时
    *   }
    *
    *   let c = foo(a) //函数foo(a)的返回值 赋值给 全局变量c；经过刚刚函数内的一顿操作 现在将函数的返回值赋值给全局变量c 就是新对象银时
    *   console.log(a === c) //打印 全局变量a所指向的对象sherry 是否全等于 全局变量c所指向的新对象银时 false
    *   console.log(a.name,c.name) //打印 全局变量a所指向的对象sherry的name属性 打印全局变量c所指向的对象银时的name属性
    *
    *
    *
    *   在js中使用 === 比较对象的时候 其实是从内存中判断他们是不是同一个堆 属于同一个内存空间
    *
    *
    *
    * */



</script>
</body>
</html>